package com.biz.primus.ms.promotion.service.promotion;

import com.biz.primus.base.enums.CommonStatus;
import com.biz.primus.base.exception.utils.AssertUtils;
import com.biz.primus.base.vo.PageVo;
import com.biz.primus.common.utils.JsonUtils;
import com.biz.primus.common.vo.SpringPageVO;
import com.biz.primus.model.promotion.exception.PromotionExceptionType;
import com.biz.primus.model.promotion.vo.DiscountPromotionRuleVo;
import com.biz.primus.model.promotion.vo.DiscountPromotionVo;
import com.biz.primus.ms.base.service.AbstractBaseService;
import com.biz.primus.ms.promotion.dao.po.DiscountPromotion;
import com.biz.primus.ms.promotion.dao.repository.DiscountPromotionRepository;
import com.biz.primus.ms.promotion.trans.DiscountPromotionPo2VoMapper;
import com.google.common.collect.Lists;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 折扣促销后台管理ServiceImpl
 *
 * @author david-liu
 */
@Service
public class DiscountPromotionManagementServiceImpl extends AbstractBaseService implements DiscountPromotionManagementService {

    @Autowired
    private DiscountPromotionRepository discountPromotionRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateDiscountPromotion(DiscountPromotionVo vo) {
        AssertUtils.notNull(vo, PromotionExceptionType.ILLEGAL_PARAMETER);
        DiscountPromotion discountPromotion;
        if (Objects.isNull(vo.getId())) {
            discountPromotion = new DiscountPromotion();
            discountPromotion.setId(idService.getNextId());
        } else {
            discountPromotion = discountPromotionRepository.findOne(vo.getId());
            AssertUtils.notNull(discountPromotion, PromotionExceptionType.ILLEGAL_STATE);
        }
        discountPromotion.setName(vo.getName());
        discountPromotion.setDescription(vo.getDescription());
        discountPromotion.setChannels(vo.getChannels());
        discountPromotion.setStartTime(LocalDateTime.from(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").parse(vo.getStartTime())));
        discountPromotion.setEndTime(LocalDateTime.from(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").parse(vo.getEndTime())));
        discountPromotion.setEffectMemberLevels(Optional.ofNullable(vo.getEffectMemberLevels()).orElse(Lists.newArrayList()).stream().map(Integer::valueOf).collect(Collectors.toList()));
        discountPromotion.setAllowCoupon(vo.getAllowCoupon());
        discountPromotion.setScope(vo.getScope());
        discountPromotion.setScopeIds(Arrays.stream(StringUtils.split(vo.getScopeIds(), ",")).map(id -> Long.valueOf(StringUtils.trim(id))).collect(Collectors.toList()));
        discountPromotion.setCommonStatus(vo.getCommonStatus());
        discountPromotion.setIsStairCut(vo.getIsStairCut());
        DiscountPromotionRuleVo ruleVo = new DiscountPromotionRuleVo();
        ruleVo.setIsStairCut(vo.getIsStairCut());
        ruleVo.setLimitType(vo.getLimitType());
        ruleVo.setDiscountRates(vo.toRateMap());
        discountPromotion.setDiscountPromotionRule(JsonUtils.obj2Json(ruleVo));
        discountPromotionRepository.save(discountPromotion);
        return true;
    }

    @Override
    public SpringPageVO<DiscountPromotionVo> getDiscountPromotions(PageVo pageVo) {
        Page<DiscountPromotion> page = discountPromotionRepository.findAll(pageVo.toPageRequest());
        if (!page.hasContent()) {
            return new SpringPageVO<>();
        }
        List<DiscountPromotionVo> promotionVoList = new DiscountPromotionPo2VoMapper().mapWithList(page.getContent());
        return new SpringPageVO.Builder<DiscountPromotionVo>().number(page.getNumber()).size(page.getSize()).content(promotionVoList).totalElements(page.getTotalElements()).build();
    }

    @Override
    public DiscountPromotionVo getDiscountPromotion(Long promotionId) {
        AssertUtils.notNull(promotionId, PromotionExceptionType.ILLEGAL_PARAMETER);
        DiscountPromotion discountPromotion = discountPromotionRepository.findOne(promotionId);
        AssertUtils.notNull(discountPromotion, PromotionExceptionType.ILLEGAL_STATE);
        return new DiscountPromotionPo2VoMapper().map(discountPromotion);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean toggleDiscountPromotionStatus(Long promotionId) {
        AssertUtils.notNull(promotionId, PromotionExceptionType.ILLEGAL_PARAMETER);
        DiscountPromotion discountPromotion = discountPromotionRepository.findOne(promotionId);
        AssertUtils.notNull(discountPromotion, PromotionExceptionType.ILLEGAL_STATE);
        discountPromotion.setCommonStatus(CommonStatus.toggle(discountPromotion.getCommonStatus()));
        discountPromotionRepository.save(discountPromotion);
        return true;
    }
}
